/* @flow */

import { isDef,remove  } from '../../util/index'




function pruneCacheEntry (
  cache,
  key,
  keys,
  current
) {
  const cached = cache[key]
  if (cached && (!current || cached.tag !== current.tag)) {
    cached.componentInstance.$destroy()
  }
  cache[key] = null
  remove(keys, key)
}


export default {
  name: 'keep-alive',
  abstract: true,
  created () {
    this.cache = Object.create(null)
    this.keys = []
  },
  render () {
    //获取插槽内容
    const slot = this.$slots.default
    //找出第一个是组件的vnode
    const vnode =  getFirstComponentChild(slot)
    const componentOptions = vnode && vnode.componentOptions
    //获取组件的配置options
    if (componentOptions) {
      const { cache, keys } = this
      const key = vnode.key == null
        ? componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
        : vnode.key
      //存在于缓存中
      if (cache[key]) {
        vnode.componentInstance = cache[key].componentInstance
        remove(keys, key)
        keys.push(key)
      } else {
        cache[key] = vnode
        keys.push(key)
        //缓存有数量，超过会去掉最新缓存的那个
        if (this.max && keys.length > parseInt(this.max)) {
          pruneCacheEntry(cache, keys[0], keys, this._vnode)
        }
      }

      vnode.data.keepAlive = true
    }
    return vnode || (slot && slot[0])
  }
}


function getFirstComponentChild (children) {
  if (Array.isArray(children)) {
    for (let i = 0; i < children.length; i++) {
      const c = children[i]
      if (isDef(c) && (isDef(c.componentOptions))) {
        return c
      }
    }
  }
}
